package timing.ukulele.storage.controller.minio;

import io.minio.PostPolicy;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.storage.service.minio.PreSignedService;
import timing.ukulele.web.controller.BaseController;

import java.util.Map;

/**
 * preSigned相关操作接口
 */
@RestController
@RequestMapping("/preSigned")
@Tag(name = "PreSigned的相关操作接口")
@Slf4j
public class PreSignedController extends BaseController {
    private final PreSignedService preSignedService;

    public PreSignedController(PreSignedService preSignedService) {
        this.preSignedService = preSignedService;
    }

    @GetMapping("/object")
    @Operation(summary = "生成一个给HTTP GET请求用的presigned URL。浏览器/移动端的客户端可以用这个URL进行下载，即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间，默认值是7天")
    public ResponseData<String> getObject(@Parameter(description = "存储桶名称", required = true, name = "bucketName", in = ParameterIn.QUERY) @RequestParam("bucketName") String bucketName,
                                          @Parameter(description = "存储桶里的对象名称", required = true, name = "objectName", in = ParameterIn.QUERY) @RequestParam("objectName") String objectName,
                                          @Parameter(description = "失效时间（以秒为单位），默认是7天，不得大于七天", example = "7200", name = "expires", in = ParameterIn.QUERY) @RequestParam(value = "expires", required = false) Integer expires) {
        try {
            String objectUrl = this.preSignedService.preSignedGetObject(bucketName, objectName, expires);
            return successResponse(objectUrl);
        } catch (Exception e) {
            log.error(e.getMessage());
            return failResponse(null, e.getMessage());
        }
    }

    @PostMapping("/object/policy")
    @Operation(summary = "允许给POST请求的presigned URL设置策略，比如接收对象上传的存储桶名称的策略，key名称前缀，过期策略")
    public ResponseData<Map<String, String>> postPolicy(@Parameter(description = "要赋予的策略", name = "policy", in = ParameterIn.QUERY) @RequestParam(value = "policy", required = false) PostPolicy policy) {
        try {
            Map<String, String> map = this.preSignedService.preSignedPostPolicy(policy);
            return successResponse(map);
        } catch (Exception e) {
            log.error(e.getMessage());
            return failResponse(null, e.getMessage());
        }
    }
}
